PATH
MacOS X Server Release Notes Copyright \xa9 1998 by Apple Computer, Inc. All Rights Reserved.
This file contains release notes for the Mac OS X Server release of the JavaBeans palette for InterfaceBuilder. The JavaBeans palette lets one manipulate JavaBeans inside InterfaceBuilder, and freely mix and match YellowBox and Java user interface and logic components in a single interface (nib) file.
After starting InterfaceBuilder, choose Open... from the Palettes submenu located in the Tools menu. Then choose /System/Developer/Palettes/JavaBeans.palette and click OK: the JavaBeans palette will appear in the palettes window. The palette contains 2 icons: the one on the left is used for non-GUI beans while the one on the right is used for GUI beans. The non-GUI beans icon can be dropped in the document window while the GUI beans icon can be dropped into any NSWindow or NSPanel.
Mac OS X Server is the first release in which the JavaBeans palette is available. Its most important features are:
The JavaBeans that will be manipulated in InterfaceBuilder are found in different locations: on the system class path (set using the DefaultClasspath entry of the system's Library/JavaConfig.plist file or the CLASSPATH environment variable, which defaults to the configuration file value) and on another path called the bean path.
The bean path acts much like the class path but is simply interpreted differently: if a component of the bean path is a directory, then it comprises all the .jar and .mf files in this directory; if it is a file whose filename ends in .jar or .mf, it comprises this file. Otherwise, the component is ignored.
The bean path can be set similarly to the class path: either using the DefaultBeanpath entry of the system's Library/JavaConfig.plist file or the BEANPATH environment variable. Path components are separated by the same path separator used for the class path.
It is important to note that this bean path applies both at design time and at runtime. There is currently no support for managing the bean path from within InterfaceBuilder or ProjectBuilder. Please note too that dropping a .jar file in InterfaceBuilder does not change the bean path except within the current running InterfaceBuilder. This change will be lost as soon as one quits InterfaceBuilder and the bean path will have to be set correctly before any nib file containing beans from the addes .jar files can be loaded or used.
Beans can also be found by simply dropping a .jar or .mf file onto an open InterfaceBuilder file. When this is done, the JavaBeans palette will look in the archive and record any beans found therein. The beans found will then be availble in the Choose Bean panel shown after dropping one of the bean icons from the palette. As noted above, the path to the dropped file is only remembered for the currently running instance of IB, it is not added to the bean path. Because of this, beans used from the dropped file may not be found at runtime.
If two archives on the bean path have the same base name regardless of the file extension (ie. if the last components of the archives path, after dropping the extension, are the same), only the first archive will be available to choose beans from.
If two archives define the same class or interface, the one being used is not defined. In other words, do not allow this to happen or you might end up in trouble because the outcome is non-deterministic. A later release of the JavaBeans palette will likely offer a way to resolve or determine the outcome of such conflicts.
The JavaBeans palette supports reading custom manifest files which are not inside of a .jar file. Custom manifest files are used to address the case when one has an archive of Java classes that was not packaged with beans information, or with incorrect one. Rather than change this archive (which could be a .zip file on your system class path, as it happens for the classes.zip file containing the AWT classes on some platforms), you can simply write a manifest file that will be found on the bean path and read by the JavaBeans palette. This file must have .mf as its extension. If its base name is the same as some existing .jar file (e.g. for a file called MyBeans.jar the manifest file must be named MyBeans.mf) and it is first on the bean path, it will override any beans information in that file.
A sample .mf file looks like:
Manifest-Version: 1.0
Archive-Display-Name: My Custom Beans
Name: com/their/company/demo/DemoSource.class
Java-Bean: True
Name: com/their/company/demo/DemoTarget.class
Java-Bean: True
Name: com/their/company/archive/TableSource.ser
Java-Bean: True
Note that separate entries must be separated by an empty line and that the very first line of the manifest file must be the one shown above (the version number can change; at the time of writing, Sun only defines the 1.0 manifest file format). Other keys that the JavaBeans palette recognizes are as follows:
The connection model used when a connection is being made depends on the kind of object that is the source of the connection. The goal here is to give the best connection experience for mixed worlds connections.
If the source is a Yellow Box component, the connection will use the AppKit's target-action paradigm with a simple extension: valid actions for a Java bean will be methods returning void and taking either no arguments or a single java.lang.Object argument. If the target accepts an argument, this will be the source of the connection when it is messaged. That is, the argument will be "sender" as it is with all AppKit widgets.
If the source is a Java bean and the destination is a Yellow Box component, by design the Yellow Box component's action will take a single java.lang.Object argument. The Object that will be passed will be the source of the event; one expects this object to be the source of the connection, so the net effect is that Yellow Box components get the sender they expect to get from both Yellow Box components and JavaBeans. (Note that the JavaBeans palette also supports non-standard event method signatures as defined by the JavaBeans specification. In the case of such event methods, the sender will be the first java.lang.Object argument of the event method.)
If both the source and destination are JavaBeans, the destination methods will be methods returning void and taking (a) no arguments, (b) a single java.lang.Object argument or (c) arguments compatible with the source's event method signature. The latest methods are not listed in the classes browser informations, as they need to match the source method: they will only appear in the connection inspector when needed.
Outlets are instance variables that are visible for connection in InterfaceBuilder. The JavaBeans specification only covers setting the value of variables using editors, and there is no editor for setting object values.
In InterfaceBuilder, outlets are instance variables found using one of the following methods.
An instance variable is an outlet if its name ends by "Outlet". Here are some instance variables, and an indication of whether they would qualify or not:
private Object delegateOutlet; // Qualify as an outlet.
protected Button outlet; // Does not qualify: outlet is not capitalized.
private TextArea _myText_Outlet; // Qualify.
private Component myOutletComp; // Does not qualify: Outlet is not at the end.
protected Label myLabel; // Does not qualify, obviously.
The bean can also give a list of its outlet names. If such a list is present, the outlet naming convention method of discovering beans is not used. The list of outlet names must be in a public static array of String objects named __ibOutletNames. Here is the previous example using this method:
private Object delegateOutlet; // Ignored even though it would qualify.
protected Button outlet; // Got even though it would not qualify.
private TextArea _myText_Outlet; // Ignored even though it would qualify.
private Component myOutletComp; // Ignored but would not qualify anyway.
protected Label myLabel; // Got even though it would not qualify.
public static final String[] __ibOutletNames = {
"outlet",
"myLabel",
"myText"
};
Note that the myText outlet will be ignored by InterfaceBuilder if there is no instance variable with such a name. Also note that only instance variables listed in this array will be displayed in InterfaceBuilder's property sheet for the bean.
Also please note that in this release this variable has to be public to be accessed by InterfaceBuilder's introspection code.
ProjectBuilder currently doesn't directly support creating and packaging JavaBeans but with a couple small makefile additions this can be done very easily. Here are the steps that you should follow for creating a JavaBeans package with ProjectBuilder:
When a bean is inserted into a nib file, the bean is "wrapped" by a Yellow Box object. For graphical beans the wrapper class is an NSBeanView whereas for non-graphical beans, the wrapper class is an opaque wrapper class. Both of these objects conform to the NSBeanHolder protocol which defines an instance method called bean (or java.lang.Object bean() in Java) which will return the actual Java bean object itself. Once you have the bean object you can manipulate it normally.
The declaration for the NSBeanView class and the NSBeanHolder protocol are
available by importing
Please note again that this only applies when one is manipulating a Java bean from a Yellow Box object, and only when the Java bean is assigned to an outlet of the Yellow Box object (or can be found by it, as when an NSView instance looks at its subviews). Outlets of Java beans are directly set to other Java beans rather than to their covers, and senders of actions are the real Java beans too.
When a Java bean is saved in a nib file it is serialized, as opposed to having source code generated as many other graphical bean development tools do. Because of this all JavaBeans that you use in InterfaceBuilder must implement either java.io.Serializable or java.io.Externalizable. Although this is specified in the JavaBeans specification (it is actually required by the specification but unfortunately not enforced by the sample beanbox tool), it appears that a wide range of beans don't adhere to this rule and will not work in InterfaceBuilder. When a bean is found by the JavaBeans palette which claims to be a bean but does not implement one of the serialization interfaces, it is not accepted as a true bean. A message is logged on the console indicating this and the bean will not be displayed in the Choose Bean panel.
Another thing to note when dealing with serialized beans is that when a Java object is serialized it includes a version number. If the Java class changes at a later time it may not be able to unserialize the object properly. When this happens a java.io.InvalidClassException is thrown with a reason saying, "com.apple.MyBean ; Local class not compatible: stream classdesc serialVersionUID=-26877342348795729384 local class serialVersionUID=-532342389427839487234". You can avoid this by specifying a serialVersionUID in the bean's class. See the JDK documentation for more details on how to do this and how to use the serialver utility for generating version numbers.
The JavaBeans palette provides event adapters for the standard AWT and
Swing (the JFC user interface framework) event types. If the beans you use in your nib files define custom event types then a custom event adapter class will be automatically generated
if needed. Adapters classes are needed whenever one connects an event to an
action; the adapter's role is to register as a listener to this event and
to invoke the appropriate action when the event is fired. The first time one of these adapters is needed (when going into Test Interface mode in InterfaceBuilder or by loading the nib file in an application) there is a small delay (on the order of 10 seconds) due to this generation of the adapter class. This delay is on a per-user but does only happen on the first use of the adapter.
Reference | 225648 |
Problem | The Java connection inspector does not support multicast. |
Description | It is currently impossible to connect many destinations from a single event within InterfaceBuilder. This is due to a limitation in InterfaceBuilder. |
Workaround | Do the additional connections programatically, in the void awakeFromNib() method of your nib file owner. |
Reference | 2252662 |
Problem | Window beans are not supported. |
Description | The Java Beans palette does not offer the developer to choose amongst window beans, even if some were found on the system bean path. It is thus impossible to manipulate beans that are windows. |
Workaround | None. |
Reference | 2253370 |
Problem | System beans class information can be edited. |
Description | Class information added to the classes browser for each bean class (and superclasses) is editable by the user. Editing this information, though, can lead InterfaceBuilder into letting one do incorrect connections or preventing one to do correct connections because connectivity is partly based on this information, which is assumed to be correct. |
Workaround | Do not edit information for classes that you do not control. |
Reference | 2250818 |
Problem | JavaBeans palette should have a CustomView equivalent |
Description | On the normal InterfaceBuilder palette for YellowBox widgets there is a CustomView object which lets you create an instance of an NSView subclass without having the code for that class loaded. The JavaBeans palette has no synonymous way of creating a java.awt.Component subclass. |
Workaround | Create a custom .mf file for the .jar file containing the class you want to instantiate and list this .mf file on the bean path before the jar file containing the bean. By doing this the .mf file will be found and the class(es) listed in the file will be available in the Choose Bean panel. |
Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries.